#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import os
import time

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.select import Select
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from common.path_setting import ensure_path_sep
from common.get_logger import GetLogger
from config import config
from common.yaml_util import YamlUtil

log = GetLogger.get_logger()


class Library:

    def __init__(self):
        self.driver = None

    def open_browser_old(self, page_name, browser):
        """打开浏览器并最大化页面"""
        download_directory = ensure_path_sep("\\outputs\\downloads")
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_experimental_option("prefs", {
            "downloads.default_directory": download_directory,
            "downloads.prompt_for_download": False,
            "downloads.directory_upgrade": True,
            "safebrowsing.enabled": False
        })

        try:
            browser = browser.capitalize()
            if browser == "Chrome":
                self.driver = getattr(webdriver, browser)(options=chrome_options)
                self.driver.maximize_window()
                log.info(f"打开浏览器，所属页面为【{page_name}】")
            else:
                self.driver = getattr(webdriver, browser)()
                self.driver.maximize_window()
                log.info(f"打开浏览器，所属页面为【{page_name}】")
            # 加个隐式等待，增加稳定性，但是降低效率
            self.driver.implicitly_wait(3)
        except Exception as e:
            log.warning(f"打开浏览器失败，失败原因为：{e}")
            raise e

    def open_browser(self, page_name, browser):
        headless = config.headless
        """打开浏览器并最大化页面"""
        download_directory = ensure_path_sep("\\outputs\\downloads")
        # log.info(f"指定文件下载路劲为：{download_directory}")

        browser_options = {
            "Chrome": webdriver.ChromeOptions(),
            "Firefox": webdriver.FirefoxOptions()
            # 添加其他浏览器选项
        }

        if headless:
            browser_options["Chrome"].add_argument("--headless")
            browser_options["Firefox"].add_argument("--headless")

        browser_options["Chrome"].add_experimental_option("prefs", {
            "download.default_directory": download_directory,  # 指定下载文件夹路径
            "download.prompt_for_download": False,  # 禁止下载提示框
            "download.directory_upgrade": True,  # 自动创建下载文件夹
            "safebrowsing.enabled": True  # 启用安全浏览功能
        })

        try:
            browser = browser.capitalize()
            self.driver = getattr(webdriver, browser)(options=browser_options.get(browser, None))
            # 最大化可以分开封装
            self.driver.maximize_window()
            log.info(f"打开浏览器，所属页面为【{page_name}】")
        except Exception as e:
            log.warning(f"打开浏览器失败，失败原因为：{e}")
            raise e

    def load_url(self, page_name, url=config.default_url):
        """
        加载连接，不输入url则默认使用config中的默认url
        :param page_name:
        :param url: 需要打开的连接
        :return:
        """
        try:
            self.driver.get(url)
            log.info(f"加载连接，所属页面为【{page_name}】")
        except Exception as e:
            log.warning(f"加载连接失败，失败原因为：{e}")
            raise e

    def locator(self, page_name, loc_type, loc_value):
        """元素定位"""
        # WebElement对象
        try:
            el = self.driver.find_element(loc_type, loc_value)
            # log.info(f"在【{page_name}】，定位到元素：{loc_type, loc_value}")
        except:
            log.error(f"在【{page_name}】，未定位到元素：{loc_type, loc_value}！！！")
            # 失败截图
            # self.sava_page_shot(page_name)
            raise NoSuchElementException
        return el

    def wait_ele_clickable(self, page_name, loc_type, loc_value, timeout: float = 15, poll_fre: float = 0.5):
        """
        等待元素可见
        :param page_name:
        :param loc_type, loc_value:
        :param timeout:
        :param poll_fre:
        :return:
        """
        try:
            # WebDriverWait(self.driver, timeout, poll_fre).until(ec.visibility_of_element_located((loc_type, loc_value)))
            WebDriverWait(self.driver, timeout, poll_fre).until(ec.element_to_be_clickable((loc_type, loc_value)))
            # WebElement对象
            # log.info(f"在【{page_name}】，元素：{loc_type, loc_value} 可见")
        except Exception as e:
            log.error(f"在【{page_name}】，元素：{loc_type, loc_value} 不可见！！！")
            raise e

    def wait_ele_presence(self, page_name, loc_type, loc_value, timeout: float = 10, poll_fre=0.5):
        """
        等待元素存在，用于断言
        presence_of_element_located最宽松，只要求元素出现在DOM树中，
        visibility_of_element_located要求元素可见，
        而element_to_be_clickable最严格，要求元素可见且可点击
        :param page_name:
        :param loc_type:
        :param loc_value:
        :param timeout:
        :param poll_fre:
        :return:
        """
        try:
            WebDriverWait(self.driver, timeout, poll_fre).until(ec.presence_of_element_located((loc_type, loc_value)))
            log.info(f"在【{page_name}】，用于断言的，元素：{loc_type, loc_value} 存在")
            return True
        except:
            log.info(f"在【{page_name}】，用于断言的，元素：{loc_type, loc_value} 不存在，返回False")
            return False

    def input(self, page_name, loc_type, loc_value, value=None, timeout=15):
        """输入"""
        try:
            # 等待元素可见
            self.wait_ele_clickable(page_name, loc_type, loc_value, timeout=timeout)
            self.locator(page_name, loc_type, loc_value).clear()
            self.locator(page_name, loc_type, loc_value).send_keys(Keys.CONTROL, 'a')
            # 需要输入内容的时候，输入为空的时候进行清空操作，不进行输入操作
            if value is not None:
                self.locator(page_name, loc_type, loc_value).send_keys(value)
                log.info(f"在【{page_name}】，元素{loc_type, loc_value}清空原有内容并且输入:{value}")
        except Exception as e:
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            log.error(f"在【{page_name}】，元素{loc_type, loc_value}输入失败！")
            raise e

    def click(self, page_name, loc_type, loc_value, timeout=15):
        """点击"""
        try:
            # 等待元素可见
            self.wait_ele_clickable(page_name, loc_type, loc_value, timeout=timeout)
            self.locator(page_name, loc_type, loc_value).click()
            log.info(f"在【{page_name}】，点击元素{loc_type, loc_value}成功！")
        except Exception as e:
            log.error(f"在【{page_name}】，元素{loc_type, loc_value}点击失败！")
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            raise e

    def enter_keys(self, page_name, keys: list, duration_seconds: float):
        """
        :param page_name:
        :param keys: 需要按的键，传list
        :param duration_seconds: 按键长按的时间
        :return:
        """
        try:
            # 创建ActionChains对象
            action = ActionChains(self.driver)

            # 模拟按住指定的键
            for key in keys:
                action.key_down(key)

            # 执行Action并等待指定的时间
            action.perform()
            time.sleep(duration_seconds)

            # 松开所有按住的键
            for key in keys:
                action.key_up(key)
            action.perform()
            log.info(f"进行键盘操作成功，页面为：【{page_name}】，操作内容为：{keys}，持续{duration_seconds}")
        except Exception as e:
            log.error(f"进行键盘操作失败，页面为：【{page_name}】，操作内容为：{keys}，持续{duration_seconds}")
            self.sava_page_shot(page_name, page_name)
            raise e

    def quit(self, page_name):
        """关闭"""
        time.sleep(1)
        try:
            self.driver.quit()
            log.info(f"【{page_name}】关闭浏览器")
        except Exception as e:
            log.error(f"【{page_name}】关闭浏览器失败")
            # 失败截图
            self.sava_page_shot(page_name, "close_fail")
            raise e

    def sleep(self, page_name, sleep_time):
        time.sleep(int(sleep_time))
        log.info(f"在【{page_name}】，停留[{sleep_time}]秒")

    # 鼠标键盘操作。鼠标移动悬浮
    def move_element(self, page_name, loc_type, loc_value, timeout=10):
        try:
            # 等待元素可见
            self.wait_ele_clickable(page_name, loc_type, loc_value, timeout=timeout)
            ActionChains(self.driver).move_to_element(self.locator(page_name, loc_type, loc_value)).perform()
            log.info(f"在【{page_name}】，鼠标移动到元素:{loc_type, loc_value}")
        except:
            log.error(f"在【{page_name}】，鼠标移动到元素{loc_type, loc_value}失败！")
            # 失败截图
            self.sava_page_shot(page_name, page_name)

    # 移动元素1到元素2上
    def base_drag_and_drop(self, page_name, drag_source: str, drop_target: str, timeout=10):
        """
        将元素1拖动到元素2中
        :param page_name:
        :param drag_source: 元素1
        :param drop_target: 元素2
        :param timeout:
        :return:
        """
        try:
            # 等待元素可见
            log.info(f"drag_source的值为：{drag_source}")
            log.info(f"drop_target：{drop_target}")
            drag_source = json.loads(drag_source)
            drop_target = json.loads(drop_target)
            self.wait_ele_clickable(page_name, drag_source[0], drag_source[1], timeout=timeout)
            # 找到要拖动的元素和目标元素
            element_to_be_dragged = self.locator(page_name, drag_source[0], drag_source[1])
            target_element = self.locator(page_name, drop_target[0], drop_target[1])
            ActionChains(self.driver).drag_and_drop(element_to_be_dragged, target_element).perform()
            log.info(f"在【{page_name}】，将元素:{drag_source[1]} 拖到元素:{drop_target[1]}上成功")

        except Exception as e:
            log.error(f"在【{page_name}】，将元素:{drag_source[1]} 拖到元素:{drop_target[1]}上失败")
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            raise e

    def download_file(self, page_name, loc_type, loc_value, keywords, timeout=10):
        # todo 这边需要写入yaml文件调用吧，否则很麻烦
        """
        上传文件，并且获取对应的文件名，用于断言或上传文件
        :param page_name:
        :param loc_type:
        :param loc_value:
        :param keywords:写入extract文件中的键，用于其他地方拿到下载地图的地图名称
        :param timeout:
        :return:
        """
        try:
            filename = ensure_path_sep("\\outputs\\downloads")
            before = os.listdir(filename)
            # 进行下载操作
            self.click(page_name, loc_type, loc_value, timeout=timeout)
            # self.driver.find_element(By.XPATH, "//button[7]").click()
            # todo 这个时间暂定10，不好用的话，改为根据文件配置
            time.sleep(10)
            after = os.listdir(filename)
            change = set(after) - set(before)
            log.info(f"before:{before}    ,     after: {after}")
            if len(change) == 1:
                file_name = change.pop()
                log.info(f"在【{page_name}】，点击元素:{loc_type, loc_value} 下载成功，文件名为：{file_name}")
                file_path = ensure_path_sep(f"\\outputs\\downloads\\{file_name}")
                YamlUtil.write_extract_yaml({keywords: file_path})
            else:
                raise Exception("在【{page_name}】，点击元素:{loc_type, loc_value} 下载失败！不继续下面操作")
        except Exception as e:
            log.error(f"在【{page_name}】，点击元素:{loc_type, loc_value} 下载失败！")
            raise e

    def open_file(self, page_name, loc_type, loc_value, keywords):
        """
        上传文件，并且获取对应的文件名，用于断言或上传文件
        :param page_name:
        :param loc_type:
        :param loc_value:
        :param keywords:读取extract文件中的键，打开文件
        :return:
        """
        filepath = str(YamlUtil.read_extract_yaml(keywords))
        try:
            # 进行上传操作
            self.locator(page_name, loc_type, loc_value).send_keys(filepath)
            log.info("在【{page_name}】，点击元素:{loc_type, loc_value} 打开文件成功")
        except Exception as e:
            log.error(f"在【{page_name}】，点击元素:{loc_type, loc_value} 打开文件失败！文件路径为：{filepath}")
            raise e

    def upload_file(self, page_name, loc_type, loc_value, filepath):
        """
        上传文件
        :param page_name:
        :param loc_type:
        :param loc_value:
        :param filepath:
        :return:
        """
        try:
            # 进行上传操作
            self.locator(page_name, loc_type, loc_value).send_keys(ensure_path_sep(f"\\data\\{filepath}"))
            log.info("在【{page_name}】，点击元素:{loc_type, loc_value} 打开文件成功")
        except Exception as e:
            log.error(f"在【{page_name}】，点击元素:{loc_type, loc_value} 打开文件失败！文件路径为：{filepath}")
            raise e

    # 截图
    def sava_page_shot(self, page_name, img_name):
        now_time = time.strftime('%Y%m%d%H%M%S', time.localtime())
        filename = ensure_path_sep(f"\\outputs\\screenshots\\{now_time}_{img_name}.png")
        self.driver.save_screenshot(filename)
        log.info(f"【{page_name}】失败截图，截取当前网页，存储的路径:{filename}")

    # 获取文本信息  封装
    def base_get_text(self, page_name, loc_type, loc_value, timeout=10):
        self.wait_ele_presence(page_name, loc_type, loc_value, timeout=timeout)
        text = self.locator(page_name, loc_type, loc_value).text
        log.info(f"在【{page_name}】,正在获取元素'{loc_type, loc_value}'的文本内容,文本内容为【{text}】")
        return text

    # 获取弹窗文本信息
    def base_get_alert(self, page_name, timeout=10):
        try:
            # 等待弹窗出现，设置一个合适的超时时间（秒）
            wait = WebDriverWait(self.driver, timeout)  # 这里的 10 表示最长等待时间为 10 秒
            # 等待弹窗可切换，并获取其文本
            alert = wait.until(ec.alert_is_present())
            alert_text = alert.text
            # alert_text = self.driver.switch_to.alert.text
            log.info(f"【{page_name}】正在获取弹窗文本信息,内容为'{alert_text}'")
            return alert_text
        except TimeoutException:
            log.error(f"【{page_name}】获取弹窗文本信息失败，没有找到弹窗！")
            raise TimeoutException

    # 刷新当前页面
    def base_refresh(self, page_name):
        time.sleep(3)
        log.info(f"【{page_name}】刷新页面")
        self.driver.refresh()
        time.sleep(2)

    # 下拉框选择 封装
    def base_select(self, page_name, loc_type, loc_value, types, value, timeout=10):
        """
        :param page_name:
        :param loc_type:
        :param timeout:
        :param loc_type, loc_value:元素的配置信息，格式为元祖 如：login_username = By.XPATH,"//*【name='user'】"
        :param types:  select的选择类型，有 value、index、text
        :param value: select类型对应的value，index是下标，value是value属性，text是文本内容
        """
        self.wait_ele_clickable(page_name, loc_type, loc_value, timeout=timeout)
        select = Select(self.locator(page_name, loc_type, loc_value))
        # 通过下拉框的value属性选择
        if types == "value":
            log.info("在【{}】页面,通过select的value方法点击下拉框，元素为'{}'value为'{}'".format(page_name, loc_type,
                                                                                               loc_value, value))
            select.select_by_value(value)
        # 通过下拉框的下标选择
        elif types == "index":
            log.info("在【{}】页面,通过select的index方法点击下拉框，元素为'{}'index为'{}'".format(page_name, loc_type,
                                                                                               loc_value, value))
            select.select_by_index(value)
        # 通过下拉框的文本内容选择
        elif types == "text":
            log.info("在【{}】页面,通过select的text方法点击下拉框，元素为'{}'文本内容为'{}'".format(page_name, loc_type,
                                                                                                 loc_value, value))
            select.select_by_visible_text(value)
        else:
            log.warning("在【{}】页面,元素'{}'上输入内容不正确，请检查输入内容".format(page_name, value))

    # 滚动条滚动通过调用js 封装
    def base_roll(self, page_name, x=0, y=1000):
        """
        :param page_name:
        :param x: 左边距
        :param y: 上边距
        :return:
        """
        try:
            # 设置JavaScript脚本控制滚动条,(0:左边距；1000：上边距；单位像素)
            log.info("在【{}】页面正在进行滚动操作,x为'{}',y为{}，滚动成功".format(page_name, x, y))
            js = "window.scrollTo({0},{1})".format(x, y)
            # selenium调用执行JavaScript脚本的方法
            self.driver.execute_script(js)
        except Exception as e:
            log.error("在【{}】页面正在进行滚动操作,x为'{}',y为{}，滚动失败".format(page_name, x, y))
            raise e

    # # # 返回首页
    # def base_index(self):
    #     time.sleep(3)
    #     self.driver.get(self.url)
    #     log.info(f"返回首页，地址为：【{self.url}】")

    # 切换frame
    def base_switch_frame(self, page_name, name):
        try:
            log.info(f"在【{page_name}】切换frame，name为【{name}】")
            self.driver.switch_to.frame(name)
        except Exception as e:
            log.error(f"在【{page_name}】切换frame，name为【{name}】.切换失败")
            raise f"在【{page_name}】切换frame，name为【{name}】.切换失败;错误信息为：{e}"

    # 回到默认目录界面
    def base_default_content(self, page_name):
        self.driver.switch_to.default_content()
        log.info(f"在【{page_name}】，回到默认frame")

    # 自动切换frame并切换句柄，用于动态frame使用
    def base_auto_switch_frame(self, page_name, loc_type, loc_value, frame_value):
        """

        :param page_name:
        :param loc_type:
        :param loc_value:
        :param frame_value: 可以输入id、name来获得对应的值
        :return: 用于动态frame使用
        """
        try:
            log.info(f"在【{page_name}】，正在获取frame的 {frame_value} 值")
            # 查找元素
            element = self.driver.find_element(loc_type, loc_value)
            # 获取元素的属性值
            frame_value = element.get_attribute(frame_value)

            if frame_value is None:
                log.warning(f"在【{page_name}】，找到的frame元素没有 {frame_value} 属性")
                return None

            log.info(f"在【{page_name}】，获取的frame的 {frame_value} 值为：{frame_value}")

            log.info(f"在【{page_name}】，尝试使用获取的 {frame_value} 值切换frame")
            self.driver.switch_to.frame(frame_value)
            log.info(f"在【{page_name}】，成功切换到frame，{frame_value} 值为：{frame_value}")
            return frame_value
        except Exception as e:
            log.error(f"在【{page_name}】，获取并切换frame的 {frame_value} 值失败，错误信息：{e}")
            raise Exception(f"在【{page_name}】获取并切换frame的 {frame_value} 值失败; 错误信息为：{e}")

    # 切换窗口 方法 调用此方法
    def base_switch_to_window(self, page_name, title):
        try:
            log.info("在【{}】，正在执行切换title值为：{}窗口 ".format(page_name, title))
            self.driver.switch_to.window(self.base_get_title_handle(page_name, title))
        except Exception as e:
            log.error("在【{}】，切换title值为：{}窗口失败".format(page_name, title))

    # 获取指定title页面的handle方法
    def base_get_title_handle(self, page_name, title):
        # 获取当前页面所有的handles
        for handle in self.driver.window_handles:
            log.info("正在遍历handles：{}-->{}".format(handle, self.driver.window_handles))
            # 切换 handle
            self.driver.switch_to.window(handle)
            log.info("切换 :{} 窗口".format(handle))
            # 获取当前页面title 并判断 是否等于 指定参数title
            log.info("判断当前页面title:{} 是否等于指定的title:{}".format(self.driver.title, title))
            if self.driver.title == title:
                log.info("【{}】,条件成立！ 返回当前handle{}".format(page_name, handle))
                # 返回 handle
                return handle

    # 封装方法，可以调用当前类下面的所有的关键字函数
    def run(self, keyword, *args):
        # 调用关键字，基于反射
        try:
            getattr(self, keyword)(*args)
        except Exception as e:
            log.error(f"执行步骤失败，请检查输入是否正确，输入内容为：{keyword} 和 {args}")
            raise e

    def assert_equal_text(self, page_name, loc_type, loc_value, expect):
        res = self.base_get_text(page_name, loc_type, loc_value, timeout=10)
        if res != expect:
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            log.error(f"【{page_name}】断言失败，期望结果：【{expect}】 ！= 实际结果：【{res}】")
            raise Exception(f"【{page_name}】断言失败，期望结果：【{expect}】 ！= 实际结果：【{res}】")
        else:
            log.info(f"【{page_name}】断言成功，期望结果：【{expect}】 == 实际结果：【{res}】")

    def assert_not_equal_text(self, page_name, loc_type, loc_value, expect):
        res = self.base_get_text(page_name, loc_type, loc_value, timeout=10)
        if res == expect:
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            log.error(f"【{page_name}】断言失败，期望结果：【{expect}】 应该不等于 实际结果：【{res}】")
            raise Exception(f"【{page_name}】断言失败，期望结果：【{expect}】 应该不等于 实际结果：【{res}】")
        else:
            log.info(f"断言类型：文本不相等，【{page_name}】断言成功，期望结果：【{expect}】 ！= 实际结果：【{res}】")

    def assert_true(self, page_name, loc_type, loc_value, timeout=5):
        res = self.wait_ele_presence(page_name=page_name, loc_type=loc_type, loc_value=loc_value, timeout=timeout)
        if res is False:
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            log.error(f"【{page_name}】断言失败,元素不存在，元素信息为：{loc_type}和{loc_value}")
            raise Exception(f"【{page_name}】断言失败,元素不存在，元素信息为：{loc_type}和{loc_value}")
        else:
            log.info(f"【{page_name}】断言成功,元素存在")

    def assert_text_contains(self, page_name, loc_type, loc_value, expect):
        """
        断言元素的文本是否包含预期文本
        :param page_name: 页面名称
        :param loc_type: 定位类型
        :param loc_value: 定位值
        :param expect: 预期包含的文本
        """
        res = self.base_get_text(page_name, loc_type, loc_value, timeout=10)
        if expect not in res:
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            log.error(f"【{page_name}】断言失败，期望结果：【{expect}】 未包含在 实际结果：【{res}】中")
            raise Exception(f"【{page_name}】断言失败，期望结果：【{expect}】 未包含在 实际结果：【{res}】中")
        else:
            log.info(f"断言类型：文本包含，【{page_name}】断言成功，期望结果：【{expect}】 包含在 实际结果：【{res}】中")

    def assert_false(self, page_name, loc_type, loc_value, timeout=5):
        """
        用于判断某个元素不存在的
        :param timeout:
        :param page_name:
        :param loc_type:
        :param loc_value:
        :return:
        """
        res = self.wait_ele_presence(page_name=page_name, loc_type=loc_type, loc_value=loc_value, timeout=timeout)
        if res is True:
            # 失败截图
            self.sava_page_shot(page_name, page_name)
            log.error(f"【{page_name}】断言失败,元素应该是不存在的")
            raise Exception(f"【{page_name}】断言失败,元素期望是不存在的")
        else:
            log.info(f"【{page_name}】断言成功,该元素期望是不存在的")

    def assert_element_not_clickable(self, page_name, loc_type, loc_value, timeout=5):
        """
        断言元素不可点击
        :param page_name: 页面名称
        :param loc_type: 定位类型
        :param loc_value: 定位值
        :param timeout: 超时时间
        """
        try:
            WebDriverWait(self.driver, timeout).until(ec.element_to_be_clickable((loc_type, loc_value)))
            # 如果元素在指定时间内变为可点击，则断言失败
            self.sava_page_shot(page_name, page_name)
            log.error(f"【{page_name}】断言失败，元素：{loc_type}和{loc_value} 是可点击的")
            raise Exception(f"【{page_name}】断言失败，元素：{loc_type}和{loc_value} 是可点击的")
        except TimeoutException:
            # 若超时仍不可点击，则断言成功
            log.info(f"【{page_name}】断言成功，元素：{loc_type}和{loc_value} 不可点击")

    def login(self, pagename, app, uesrname, password):
        if app in ["kmo", "kbs", "ksd"]:
            # 判断当前是否已经登录，通过导航栏的用户元素进行判断
            if self.wait_ele_presence(pagename, "css selector",
                                      "div[class='dw-f-text-link ant-dropdown-trigger'] span[class='show-name']",
                                      timeout=2):
                log.info("已经登录，不需要登录")
                return
            else:
                # 进行登录操作
                self.input(pagename, "css selector", "input[placeholder='请输入用户帐号或手机号或E-mail']", uesrname)
                self.input(pagename, "css selector", "input[placeholder='密码']", password)
                self.click(pagename, "css selector", "button[type='submit']")
                time.sleep(5)
                if self.wait_ele_presence(pagename, "css selector",
                                          "div[class='dw-f-text-link ant-dropdown-trigger'] span[class='show-name']"):
                    log.info("登录成功")
                else:
                    log.error("登录失败")
                    raise Exception("登录失败，app为{app}，账号密码为：{uesrname} ，{password}")
        else:
            log.warning(f"app的值错误，输入了：{app}")
            raise Exception(f"app的值错误，输入了：{app}")

    # 选择租户
    def select_tenant(self, pagename, app, tenant):
        if app in ["kmo", "kbs"]:
            # 获取当前租户
            now_tenant = self.base_get_text(pagename, "css selector", "body app-root app-tenant-info span:nth-child(2)")
            log.info(f"当前租户为：{now_tenant}")
            if now_tenant == tenant:
                log.info(f"当前租户为：{now_tenant}，不需要切换租户")
                return
            else:
                self.click(pagename, "css selector", "body app-root app-tenant-info span:nth-child(2)")
            time.sleep(3)
            # 切换到测试租户
            self.click(pagename, "xpath", f"//a[contains(text(),'{tenant}')]")
            # self.click(pagename, "xpath", "//a[contains(text(),'知识中台评审租户')]")
            time.sleep(1)
            self.click(pagename, "xpath", "//span[contains(text(),'确定')]")
            time.sleep(3)
            # 判断最新租户是否正确
            now_tenant = self.base_get_text(pagename, "css selector", "body app-root app-tenant-info span:nth-child(2)")
            log.info(f"切换租户成功，当前租户为：{now_tenant}")
            time.sleep(3)
        else:
            log.warning(f"app的值错误，输入了：{app}")
            raise Exception(f"app的值错误，输入了：{app}")


if __name__ == '__main__':
    print("heeee")
    # print(config.default_url)
    # filename = ensure_path_sep("\\outputs\\downloads")
    # print(filename)

    print(ensure_path_sep("\\outputs\\downloads"))
